package com.henry.db.migrate.task;

import com.henry.db.migrate.factory.DbFactory;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.log4j.Logger;

import java.sql.Connection;
import java.util.List;
import java.util.Map;

public class MigrateThread implements Runnable {
    private static final Logger logger = Logger.getLogger(MigrateThread.class);
    private ThreadGroup group;
    private BaseTable baseTable;
    private int num;

    public MigrateThread(ThreadGroup group, BaseTable baseTable, int num) {
        this.group = group;
        this.baseTable = baseTable;
        this.num = num;
    }

    @Override
    public void run() {
        logger.info("线程组[" + group.getName() + "]中的线程[" + num + "]正在运行...");
        QueryRunner runner = new QueryRunner();
        Connection srcConn = DbFactory.getConnection("src");
        Connection targetConn = DbFactory.getConnection("target");
        try {
            String insertSql = genInsertSql(baseTable);
            String querySql = genQuerySql(baseTable);
            List<Map<String, Object>> list = runner.query(srcConn, querySql, new MapListHandler());
            Object[][] params = genParams(baseTable, list);
            runner.batch(targetConn, insertSql, params);
            targetConn.commit();
        } catch (Exception e) {
            DbFactory.rollback(targetConn);
            e.printStackTrace();
        }finally {
            DbFactory.close(srcConn);
            DbFactory.close(targetConn);
        }
        logger.info("线程组[" + group.getName() + "]中的线程[" + num + "]运行结束...");

    }

    private String genQuerySql(BaseTable baseTable) {
        String sql = baseTable.getSrcSelectSql();
        int pageSize = baseTable.pageSize;
        int begin = num * pageSize;
        sql += " limit " + begin + "," + pageSize;
        return sql;
    }

    private static String genInsertSql(BaseTable baseTable) {
        StringBuilder sb = new StringBuilder();
        String table = baseTable.getTargetTable();
        String[] colnames = baseTable.getColnames();
        sb.append("insert into " + table + "(");
        for (String col : colnames) {
            sb.append(col);
            sb.append(",");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append(")values(");
        for (String col : colnames) {
            sb.append("?,");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append(")");
        return sb.toString();
    }

    private Object[][] genParams(BaseTable baseTable, List<Map<String, Object>> list) {
        String[] colnames = baseTable.getColnames();
        Object[][] params = new Object[list.size()][colnames.length];
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> map = list.get(i);
            for (int j = 0; j < colnames.length; j++) {
                params[i][j] = map.get(colnames[j]);
            }
        }
        return params;
    }
}
